import os, sys

from PyQt5 import QtGui
from PyQt5.QtWidgets import *

from protolib import rgb_to_hex, hex_to_rgb
from protolib.gui_utils.pyqt5_messageboxes import show_critical_messagebox

from strange_io.colors import StrangeColors

class MainWindow(QMainWindow):
    def __init__(self, args):
        super().__init__()

        self.setWindowIcon(QtGui.QIcon('icon.png'))
        self.setWindowTitle("Strange Colors Editor - Strange I/O")
        self.setMinimumSize(400, 500)

        #region
        menuBar = self.menuBar()
        #region
        self.fileMenu = QMenu("&File", self)
        menuBar.addMenu(self.fileMenu)
        #region
        newFileAction = QAction("&New", self)
        newFileAction.setShortcut("Ctrl+N")
        newFileAction.setStatusTip('Create new file and clear change buffer')
        newFileAction.triggered.connect(self.new_file)
        self.fileMenu.addAction(newFileAction)
        #endregion
        #region
        openFileAction = QAction("&Open", self)
        openFileAction.setShortcut("Ctrl+O")
        openFileAction.setStatusTip('Load a file from disk')
        openFileAction.triggered.connect(self.user_open_file)
        self.fileMenu.addAction(openFileAction)
        #endregion
        #region
        saveAction = QAction("&Save", self)
        saveAction.setShortcut("Ctrl+S")
        saveAction.setStatusTip('Save the file buffer to disk')
        saveAction.triggered.connect(self.save_file)
        self.fileMenu.addAction(saveAction)
        #endregion
        #region
        saveAsAction = QAction("&Save As", self)
        saveAsAction.setShortcut("Ctrl+Shift+S")
        saveAsAction.setStatusTip('Change current file and save the file buffer to disk')
        saveAsAction.triggered.connect(self.save_as_file)
        self.fileMenu.addAction(saveAsAction)
        #endregion
        self.fileMenu.addSeparator()
        #region
        quitAction = QAction("&Quit", self)
        quitAction.setShortcut("Ctrl+Q")
        quitAction.setStatusTip('Leave The App')
        quitAction.triggered.connect(self.close)
        self.fileMenu.addAction(quitAction)
        #endregion
        #endregion
        #region
        self.editMenu = QMenu("&Edit", self)
        menuBar.addMenu(self.editMenu)
        #region
        addColorAction = QAction("&Add Color", self)
        addColorAction.setShortcut("Ctrl+A")
        addColorAction.setStatusTip('Add a color to the palette')
        addColorAction.triggered.connect(self.add_color)
        self.editMenu.addAction(addColorAction)
        #endregion
        #region
        modifyColorAction = QAction("&Modify Color", self)
        modifyColorAction.setShortcut("Ctrl+E")
        modifyColorAction.setStatusTip('Modify the selected color')
        modifyColorAction.triggered.connect(self.modify_color)
        self.editMenu.addAction(modifyColorAction)
        #endregion
        #region
        removeColorAction = QAction("&Remove Color", self)
        removeColorAction.setShortcuts(["Ctrl+D", "Delete", "Alt+Backspace"])
        removeColorAction.setStatusTip('Remove the selected color')
        removeColorAction.triggered.connect(self.remove_color)
        self.editMenu.addAction(removeColorAction)
        #endregion
        #endregion
        #endregion

        #region
        self.layout = QVBoxLayout()

        self.widget = QWidget()
        self.widget.setLayout(self.layout)

        self.colorList = QListWidget()
        self.layout.addWidget(self.colorList)

        self.transperantIndexEntry = QSpinBox()
        self.transperantIndexEntry.setMaximum(255)
        self.layout.addWidget(self.transperantIndexEntry)

        self.save_button = QPushButton()
        self.save_button.setText('Save')
        self.save_button.clicked.connect(self.save_file)
        self.layout.addWidget(self.save_button)
        #endregion

        #region
        self.scolors = StrangeColors()
        self.edited = False
        self.current_file = None
        #endregion

        self.setCentralWidget(self.widget)

        if args.file_path:
            try:
                self.open_file(args.file_path)
            except os.OSError as e:
                show_critical_messagebox(e.__class__.__name__, str(e))

    def open_file(self, file_path):
        self.colorList.clear()
        self.scolors.load_file(file_path)
        for rgb_color in self.scolors.colors:
            hex_color = rgb_to_hex(rgb_color)
            item = QListWidgetItem(hex_color.upper(), self.colorList)

    def user_open_file(self):
        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        file_path, _ = QFileDialog.getOpenFileName(self, "Open file", "", "Strange Colors Palttes (*.scolors);;Strange I/O Documents (*.strange *.sio);;All Files (*)", options=options)
        if file_path:
            self.current_file = file_path
            self.open_file(file_path)

    def update_scolors_object(self):
        self.scolors.transperent_index = self.transperantIndexEntry.value()
        self.scolors.colors.clear()
        items = []
        for index in range(self.colorList.count()):
            items.append(self.colorList.item(index))
        for item in items:
            self.scolors.colors.append(hex_to_rgb(item.text()))

    def save_file(self):
        if self.current_file:
            try:
                self.update_scolors_object()
                self.scolors.dump_file(self.current_file)
            except (ValueError, OSError) as e:
                show_critical_messagebox(e.__class__.__name__, str(e))
            self.edited = False
        else:
            self.save_as_file()

    def save_as_file(self):
        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        file_path, _ = QFileDialog.getSaveFileName(self, "Save file", "", "Strange Colors Palttes (*.scolors);;Strange I/O Documents (*.strange *.sio);;All Files (*)", options=options)
        if file_path:
            try:
                self.update_scolors_object()
                self.scolors.dump_file(file_path)
                self.current_file = file_path
            except (ValueError, OSError) as e:
                show_critical_messagebox(e.__class__.__name__, str(e))
            self.edited = False

    def new_file(self):
        self.colorList.clear()
        self.scolors.colors.clear()
        self.current_file = None

    def add_color(self):
        color = QColorDialog.getColor()
        if color.isValid():
            item = QListWidgetItem(color.name().upper(), self.colorList)

    def remove_color(self):
        listItems = self.colorList.selectedItems()
        if not listItems: return
        for item in listItems:
            self.colorList.takeItem(self.colorList.row(item))

    def modify_color(self):
        listItems = self.colorList.selectedItems()
        if not listItems: return
        for item in listItems:
            color = QColorDialog.getColor(QtGui.QColor(item.text()))
            if color.isValid():
                item.setText(color.name().upper())

def main(args):
    app = QApplication(sys.argv)
    window = MainWindow(args)
    window.show()
    app.exec()
